home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Frameworks / Grant's CGI Framework 1.0b14 / Util / main.c < prev    next >
Text File  |  1996-04-11  |  8KB  |  332 lines

  1. /*****
  2.  *
  3.  *    Grant's CGI Shell (Common Grant Interface :-)
  4.  *        http://arpp.carleton.ca/grant/mac/grantscgi/
  5.  *
  6.  *    main.c
  7.  *
  8.  *    by Grant Neufeld
  9.  *
  10.  *    Copyright ©1995,1996 by Grant Neufeld
  11.  *
  12.  *    http://arpp.carleton.ca/grant/
  13.  *    gneufeld@ccs.carleton.ca
  14.  *    grant@acm.org
  15.  *
  16.  *    This source may be freely used as long as the copyright notice is kept in the source.
  17.  *    I ask that you let me know of any enhancements (read: bug fixes) to this code.
  18.  *    I would also like copies of (or discounts on) anything you produce using this code, please.
  19.  *
  20.  *****/
  21.  
  22. #define __MainSegment__    1
  23.  
  24. #include "MyConfiguration.h"
  25.  
  26. #include <string.h>
  27. #include <Threads.h>
  28. //#if __profile__ && __MWERKS__
  29. //#include <Profiler.h>
  30. //#endif
  31.  
  32. #include "compiler_stuff.h"
  33. #include "constants.h"
  34. #include "globals.h"
  35.  
  36. #include "DebugUtil.h"
  37. #include "ErrorUtil.h"
  38. #include "EventUtil.h"
  39. #include "MemoryUtil.h"
  40. #include "MenuFunc.h"
  41. #include "ProcessUtil.h"
  42. #include "Quit.h"
  43. #include "Startup.h"
  44.  
  45.  
  46. /***  LOCAL VARIABLES  ***/
  47.  
  48. static    RgnHandle    vTheMouseRgn;
  49.     
  50.  
  51. /***  LOCAL PROTOTYPES ***/
  52.  
  53. static    void    mainEventLoop        ( void );
  54. static    void    startupToolbox        ( void );
  55. static    Boolean    initAppMemory        ( void );
  56. static    OSErr    initStackGrow        ( Size );
  57.         
  58.  
  59. /***  FUNCTIONS  ***/
  60.  
  61. /* Application entry point. */
  62. void
  63. main ( void )
  64. {
  65.     /* Application is not set to quit */
  66.     gQuit = false;
  67.     
  68.     /* Included here because of InitWindows() allocation of non-relocatable blocks.
  69.         This needs to be done before any other code segments are loaded.
  70.         IM:Processes 7-5 */
  71.     /* initialize standard toolbox managers */
  72.     startupToolbox ();
  73.     
  74.     /* Included here because of MoreMasters() allocation of non-relocatable blocks.
  75.         This needs to be done before any other code segments are loaded.
  76.         IM:Processes 7-5 */
  77.     if ( !(initAppMemory()) )
  78.     {
  79.         /* inform user of insufficient memory */
  80.         ErrorStartup ( kerrStartupMemory );
  81.         ExitToShell  ();
  82.     }
  83.     
  84. //•moved to CGI.c
  85. //    #if __profile__ && __MWERKS__
  86. //    gProfileOn = !( ProfilerInit ( collectDetailed, bestTimeBase, 20, 5 ) );
  87. //    #endif
  88.     
  89.     /* do all the needed application setup */
  90.     StartupApplication ();
  91.     
  92.     /* main loop for handling system and user events */
  93.     mainEventLoop ();
  94.     
  95. //    #if __profile__ && __MWERKS__
  96. //    if ( gProfileOn )
  97. //    {
  98. //        ProfilerDump("\p" kProfileNameStr "-" kProcessorString ".prof");
  99. //        ProfilerTerm();
  100. //    }
  101. //    #endif
  102.     
  103.     ExitToShell ();
  104. } /* main */
  105.  
  106.  
  107. /* main loop for handling system and user events.
  108.     Continuously loop until application is set to quit. */
  109. static void
  110. mainEventLoop ( void )
  111. {
  112.     #if !(kCompileWithQuitOnLowMemory)
  113.     OSErr            theErr;
  114.     #endif
  115.     Boolean            eventResult;
  116.     EventRecord        event;
  117.     short            loopCounter;
  118.     
  119.     while ( !gQuit )
  120.     {
  121.         #if !(kCompileWithQuitOnLowMemory)
  122.         /* if app doesn't quit on low memory, may need to recover emergency mem */
  123.         /* IM-Memory: 1-48 */
  124.         if ( !(IsEmergencyMemAvail()) )
  125.         {
  126.             theErr = RecoverEmergencyMemory ();
  127.             if ( theErr != noErr )
  128.             {
  129.                 gQuit = true;
  130.             }
  131.         }
  132.         #endif
  133.         
  134.         #if kCompileWithThreadsOptional
  135.         if ( gHasThreadMgr )
  136.         {
  137.         #endif
  138.             /* Yield more often if there are any sub-threads. The 'more often'
  139.                 depends on how many sub-threads there are */
  140.             if ( gThreadTotal > 1 )
  141.             {
  142.                 for ( loopCounter = nil; loopCounter < gThreadTotal; loopCounter++ )
  143.                 {
  144.                     ThreadYield ( nil, false );
  145.                 }
  146.             }
  147.             else
  148.             {
  149.                 /* just yield once if there are no sub-threads, or only one */
  150.                 ThreadYield ( nil, false );
  151.             }
  152.         #if kCompileWithThreadsOptional
  153.         }
  154.         #endif
  155.         
  156.         if ( !gQuit )
  157.         {
  158.             /* wait until the next event */
  159.             eventResult = WaitNextEvent ( everyEvent, &event, gSleepTicks, nil );
  160.             if ( eventResult != nil )
  161.             {
  162.                 /* there is an event */
  163.                 /* figure out which event and process it */
  164.                 switch ( event.what ) 
  165.                 {
  166.                     case kHighLevelEvent:
  167.                         doHighLevelEvent ( &event );
  168.                         break;
  169.                     
  170.                     #if kCompileWithForeground
  171.                     /* these are interface events, only applicable if this is a
  172.                         forground application. Faceless background applications
  173.                         will not receive these events */
  174.                     
  175.                     case mouseDown:    
  176.                         doMouseDown ( &event );
  177.                         break;
  178.                     
  179.                     case mouseUp:
  180.                         doMouseUp ( &event );
  181.                         break;
  182.                     
  183.                     case keyDown:
  184.                         doKeyDown ( &event );
  185.                         break;
  186.                     
  187.                     case autoKey:
  188.                         doAutoKey ( &event );
  189.                         break;
  190.                     
  191.                     /* typically not sent to the application. IM-MTE: 2-28 */
  192.                     case keyUp:
  193.                         doKeyUp ( &event );
  194.                         break;
  195.                     
  196.                     case activateEvt:
  197.                         doActivateEvent ( &event );
  198.                         break;
  199.         
  200.                     case updateEvt:
  201.                         doUpdateEvent ( &event );
  202.                         break;
  203.                     
  204.                     /* suspend or resume */
  205.                     case osEvt:
  206.                         doOsEvt ( &event );
  207.                         break;
  208.                     
  209.                     /* disk inserted */
  210.                     case diskEvt:
  211.                         doDiskEvt ( &event );
  212.                         break;
  213.                     
  214.                     #endif    /* kCompileWithForeground */
  215.                     
  216.                     default:
  217.                         doIdle ( &event );
  218.                         break;
  219.                 }
  220.             }
  221.             else
  222.             {
  223.                 /* no event */
  224.                 doIdle ( &event );
  225.             }
  226.         }
  227.         
  228.         if ( gQuit )
  229.         {
  230.             /* the quit flag has been set, prepare to quit. If the quit
  231.                 preparation fails, the flag will be reset and we'll continue
  232.                 with the event loop. */
  233.             QuitPrepare ( true );
  234.         }
  235.     }
  236. } /* mainEventLoop */
  237.  
  238.  
  239. /***  INITIALIZATION  ***/
  240. #pragma mark -
  241.  
  242. /* initialize standard toolbox managers */
  243. static void
  244. startupToolbox ( void )
  245. {
  246.     InitGraf    ( (Ptr)(&qd.thePort) );    /* InitGraf must be first */
  247.     
  248.     #if kCompileWithForeground
  249.     /* initialize interface managers */
  250.     
  251.     InitFonts    ();
  252.     InitWindows    ();
  253.     InitMenus    ();                        /* InitMenus must be after InitWindows */
  254.     FlushEvents    ( everyEvent, nil );    /* IM-MTE: 2-93 */
  255.     TEInit        ();
  256.     InitDialogs    ( nil );                /* InitDialogs must be after TEInit */
  257.     InitCursor    ();
  258.     
  259.     #endif
  260. } /* startupToolbox */
  261.  
  262.  
  263. /* Return true if memory initialization was successful. */
  264. static Boolean
  265. initAppMemory ( void )
  266. {
  267.     short         mstrPtrsAllocated;
  268.     long         freeMemAvail;
  269.     Boolean        success;
  270.     Handle        sacrificeHandle;
  271.     
  272.     #if !(kCompileWithForeground)
  273.     /* Background only apps get a default 8K stack instead of 24K.
  274.         Increase stack size if set to background only - just to be on the safe side */
  275.     success = ( initStackGrow(16384) == noErr );
  276.     #endif
  277.     
  278.     /* NOTE: MaxApplZone must be called before any memory is allocated by threads
  279.         other than the main (application) thread. */
  280.     /* maximize available memory in the application heap */
  281.     MaxApplZone ();
  282.     
  283.     freeMemAvail = FreeMem ();
  284.     if ( freeMemAvail < kMinSegSize )
  285.     {
  286.         /* not enough memory for application to run */
  287.         success = false;
  288.     }
  289.     else
  290.     {
  291.         /* to avoid memory fragmentation, allocate master pointers at bottom of heap */
  292.         for ( mstrPtrsAllocated = 0; mstrPtrsAllocated < kMoreMasterCalls; mstrPtrsAllocated++ )
  293.         {
  294.             MoreMasters ();
  295.         }
  296.         
  297.         success = InitializeEmergencyMemory ( nil );
  298.     }
  299.     
  300.     /* Allocate a 1K memory block, force it to the top of the heap, and lock it.
  301.        This block is not used for anything - it is put at the top of the heap
  302.        as a sacrifice because sometimes MacSLIP's VBL task trashes the end of 
  303.        the heap.
  304.        from "NewsWatcher" 'newswatcher.c' */
  305.     sacrificeHandle = MemoryNewHandle ( 1024, nil );
  306.     if ( sacrificeHandle != nil )
  307.     {
  308.         HLockHi ( sacrificeHandle );
  309.     }
  310.     
  311.     return success;
  312. } /* initAppMemory */
  313.  
  314.  
  315. /*  */
  316. static OSErr
  317. initStackGrow ( Size increaseSize )
  318. {
  319.     OSErr theErr;
  320.     
  321.     my_assert ( (increaseSize % 1024) == nil, "\pinitStackGrow: size is not multiple of 1024" );
  322.     
  323.     /* Increase the stack size by lowering the heap limit. */
  324.     SetApplLimit ( (Ptr)(((unsigned long)GetApplLimit()) - increaseSize) );
  325.     theErr = MemError ();
  326.     
  327.     return theErr;
  328. } /* initStackGrow */
  329.  
  330.  
  331. /*** EOF ***/
  332.